﻿using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SX.Utils;

namespace Ly.Scheduler.NewService
{
    public class SchedulerJobListener : IJobListener
    {
        public string Name
        {
            get
            {
                return "SchedulerJobListener";
            }
        }
        /// <summary>
        /// 1 任务执行之前执行
        /// </summary>
        /// <param name="context"></param>
        public void JobToBeExecuted(IJobExecutionContext context)
        {
            System.Guid BackgroundJobId = System.Guid.Empty;
            Guid.TryParse(context.JobDetail.Key.Name, out BackgroundJobId);
            // 修改状态
            new BackgroundJobService().UpdateState(BackgroundJobId, 2);
        }

        /// <summary>
        /// 2  任务被 终止 
        /// 这个方法正常情况下不执行,但是如果当TriggerListener中的vetoJobExecution方法返回true时,那么执行这个方法.
        /// 需要注意的是 如果方法(2)执行 那么(1),(3)这个俩个方法不会执行,因为任务被终止了.
        /// </summary>
        /// <param name="context"></param>
        public void JobExecutionVetoed(IJobExecutionContext context)
        {

        }


        /// <summary>
        /// 3  任务执行完成后执行,jobException如果它不为空则说明任务在执行过程中出现了异常
        /// </summary>
        /// <param name="context"></param>
        /// <param name="jobException"></param>
        public void JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException)
        {
            int ExcuteStatus = 0;
            string ErrorMessage = "";
            System.Guid BackgroundJobId = System.Guid.Empty;
            Guid.TryParse(context.JobDetail.Key.Name, out BackgroundJobId);
            DateTime? NextFireTimeUtc = null;
            if (context.NextFireTimeUtc != null)
            {
                NextFireTimeUtc = TimeZoneInfo.ConvertTimeFromUtc(context.NextFireTimeUtc.Value.DateTime, TimeZoneInfo.Local);
            }
            DateTime? FireTimeUtc = null;
            if (context.FireTimeUtc != null)
            {
                FireTimeUtc = TimeZoneInfo.ConvertTimeFromUtc(context.FireTimeUtc.Value.DateTime, TimeZoneInfo.Local);
            }
            DateTime? PreviousFireTimeUtc = null;
            if (context.PreviousFireTimeUtc != null)
            {
                PreviousFireTimeUtc = TimeZoneInfo.ConvertTimeFromUtc(context.PreviousFireTimeUtc.Value.DateTime, TimeZoneInfo.Local);
            }
            TimeSpan JobRunTime = context.JobRunTime;
            string JobName = string.Empty;
            string LogContent = string.Empty;
            if (context.MergedJobDataMap != null)
            {
                JobName = context.MergedJobDataMap.GetString("JobName");
                string Parameters = context.MergedJobDataMap.GetString("Parameters");
                System.Text.StringBuilder log = new System.Text.StringBuilder();
                int i = 0;
                foreach (var item in context.MergedJobDataMap)
                {
                    string key = item.Key;
                    if (key.StartsWith("extend_"))
                    {
                        if (i > 0)
                        {
                            log.Append(",");
                        }
                        log.AppendFormat("{0}:{1}", item.Key, item.Value);
                        i++;
                    }
                }
                if (i > 0)
                {
                    LogContent = string.Concat("[", log.ToString(), "]");
                }
                if (Parameters.IsNotNullOrEmpty())
                {
                    LogContent += string.Format("参数:[{0}]", Parameters);
                }
            }
            Dictionary<string, string> errorDic = new Dictionary<string, string>();
            if (jobException != null)
            {
                LogContent = LogContent + " EX:" + jobException.ToString();
                ExcuteStatus = 1;
                errorDic.Add("Message", jobException.Message);
                errorDic.Add("StackTrace", jobException.StackTrace);
                errorDic.Add("Source", jobException.Source);
                errorDic.Add("InnerException", jobException.InnerException.Message);
                ErrorMessage = JsonHelper.ToJson(errorDic);
            }

            // 运行添加日志
            new BackgroundJobService().UpdateStateAndAddJobExcuteLog(BackgroundJobId, JobName,
               NextFireTimeUtc, FireTimeUtc, PreviousFireTimeUtc, (long)JobRunTime.TotalMilliseconds, LogContent, 1, ExcuteStatus, ErrorMessage);
        }
    }
}
